package io.awen.modules.sign.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.awen.common.utils.DistanceUtil;
import io.awen.common.utils.PageUtils;
import io.awen.common.utils.Query;
import io.awen.common.utils.R;
import io.awen.modules.sign.dao.SignCarLoadRecordDao;
import io.awen.modules.sign.entity.*;
import io.awen.modules.sign.qo.SignCarLoadRecordQo;
import io.awen.modules.sign.service.*;
import io.awen.modules.sys.entity.SysUserEntity;
import io.awen.modules.sys.service.SysUserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;


/**
 * 通过载重量判断车辆在卸货、装货
 * (SignCarSpeedingWarning)表服务实现类
 */
@Service("SignCarLoadRecordService")
public class SignCarLoadRecordServiceImpl extends ServiceImpl<SignCarLoadRecordDao, SignCarLoadRecordEntity> implements SignCarLoadRecordService {

    @Autowired
    private SignCarService signCarService;

    @Autowired
    private SignCarLoadRecordService signCarLoadRecordService;

    @Autowired
    private SignCarLonLatService signCarLonLatService;

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SignContainerService signContainerService;

    @Autowired
    private SignVillageTownService signVillageTownService;

    @Autowired
    private SignSinkService signSinkService;

    @Autowired
    private SignFleetService signFleetService;


    @Autowired
    private SignUnitService signUnitService;


    @Override
    public void insertWhenLoadRecord(SignCarEntity car, Double Speed, String Weight, Double lon, Double lat) {
        //拿到速度，和sign_car_lon_lat中对应的相同car_id的最新的一条记录的speed值相比较
        //如果此时的速度为0，而上一条的速度不为0，则在表里插进一条数据，字段state为0，表示状态没有完成标记，并插入开始时间的字段和weight字段
        //如果此时的速度不为0，而上一条的速度为0，则取表里的最后一条state为0的数据，更新字段state为1，且此时的字段和之前的weight差距大，表示状态完成标记，并插入结束时间的字段
        //速度不为0时，速度差距不大，则表示车辆没有在装卸货物，state更新为3，表示此时状态为停车无操作
        if (car != null && Weight != null) {
            SignCarLonLatEntity carLonLat = signCarLonLatService.getOne(new QueryWrapper<SignCarLonLatEntity>().eq("car_id", car.getId()).orderByDesc("id").last("limit 1,1"));
            if (Speed == 0) {
                if (carLonLat.getSpeed() != 0) {//停车了
                    //如果最新的一条该车辆的state为0,那么更新这条数据到最新一条上
                    SignCarLoadRecordEntity weightChange = signCarLoadRecordService.getOne(new QueryWrapper<SignCarLoadRecordEntity>().eq("sign_car_id", car.getId()).orderByDesc("id").last("limit 1"));
                    if (weightChange == null || weightChange.getState() == 2) {//上条记录为2，即卸水动作时
//                        System.out.println("尝试开始更新新纪录");
                        SignCarLoadRecordEntity entity = new SignCarLoadRecordEntity();
                        entity.setSignCarId(car.getId());
                        entity.setSignCarNumberPlate(car.getNumberPlate());
                        entity.setLon(lon);
                        entity.setLat(lat);
                        entity.setStartWeight(Double.parseDouble(Weight));
                        entity.setState(0);
                        entity.setUnitId(car.getCtUnitId());
                        entity.setCreateTime(carLonLat.getCreateTime());
                        this.save(entity);
//                        System.out.println("成功更新新纪录");
                    } else if (weightChange.getState() == 0) {//上条记录为0，即无效停车动作时

                        weightChange.setLat(lat);
                        weightChange.setLon(lon);
                        weightChange.setStartWeight(Double.parseDouble(Weight));
                        weightChange.setCreateTime(carLonLat.getCreateTime());
                        this.updateById(weightChange);

                    } else if (weightChange.getState() == 1) {//上条记录为1，即装水动作时
                        weightChange.setEndLat(lat);
                        weightChange.setEndLon(lon);

                        weightChange.setLoadStartWeight(Double.parseDouble(Weight));


                        weightChange.setStartTime(carLonLat.getCreateTime());
                        this.updateById(weightChange);

                    }

                }
            } else {
                if (carLonLat.getSpeed() == 0 && car.getRemark() == null) {//发车了
//                if (carLonLat.getSpeed() == 0) {//发车了
                    SignCarLoadRecordEntity weightChange = signCarLoadRecordService.getOne(new QueryWrapper<SignCarLoadRecordEntity>().eq("sign_car_id", car.getId()).orderByDesc("id").last("limit 1"));

                    if (weightChange != null) {

                        double change = weightChange.getStartWeight() - Double.parseDouble(Weight);
                        double change2 = weightChange.getLoadStartWeight() - Double.parseDouble(Weight);
                        if (change2 > 1000 && weightChange.getState() == 1) {
                            // 有效卸水
                            weightChange.setState(2);
                            weightChange.setLoadEndWeight(Double.parseDouble(Weight));
                            weightChange.setEndTime(carLonLat.getCreateTime());

                            Map<String, Double> vehicleWeights = new HashMap<>();
                            vehicleWeights.put("鲁BD5371", 8100.0);
                            vehicleWeights.put("鲁UK6559", 8600.0);
                            vehicleWeights.put("鲁UW8855", 4800.0);
                            vehicleWeights.put("鲁BF1987", 8600.0);
                            vehicleWeights.put("鲁BS0812", 8700.0);
                            vehicleWeights.put("鲁BJ7791", 8700.0);
                            vehicleWeights.put("鲁BT9778", 8700.0);
                            vehicleWeights.put("鲁BP6116", 8700.0);
                            vehicleWeights.put("鲁BC5113", 11700.0);
                            vehicleWeights.put("鲁B7Y0J7", 4600.0);
                            vehicleWeights.put("鲁B5E931", 4600.0);
                            vehicleWeights.put("鲁BK0008", 8100.0);
                            vehicleWeights.put("鲁B79ZB7", 4800.0);
                            //获取上一条记录signCarLonLat
                            Map<String, Double> otherWeights = new HashMap<>();
                            otherWeights.put("鲁BG7559", 12800.0);
                            otherWeights.put("鲁BH8970", 10800.0);
                            otherWeights.put("鲁BQ7918", 8800.0);
                            otherWeights.put("鲁BU8833", 8800.0);

                            weightChange.setEndLat(carLonLat.getLat());
                            weightChange.setEndLon(carLonLat.getLon());
                            if (weightChange.getSignCarNumberPlate() != null) {
                                if (vehicleWeights.containsKey(weightChange.getSignCarNumberPlate())) {
                                    //如果是这些车辆，根据后面的值取94%-99%，最小单位10
                                    double x = vehicleWeights.get(weightChange.getSignCarNumberPlate());

                                    Random rand = new Random();
                                    double maxWeight = x + 500;
                                    double randomWeight = x + rand.nextDouble() * (maxWeight - x);
                                    double tmp = randomWeight / 10;
                                    int newWeight = (int) tmp * 10;
                                    weightChange.setLoadStartWeight(newWeight);
                                } else if (otherWeights.containsKey(weightChange.getSignCarNumberPlate())) {
                                    double x = otherWeights.get(weightChange.getSignCarNumberPlate());

                                    Random rand = new Random();
                                    double maxWeight = x + 300;
                                    double randomWeight = x + rand.nextDouble() * (maxWeight - x);
                                    double tmp = randomWeight / 10;
                                    int newWeight = (int) tmp * 10;
                                    weightChange.setLoadStartWeight(newWeight);
                                }


                            }

                            List<SignSinkEntity> sinks = signSinkService.list();
                            Long sinkId = DistanceUtil.getNearestSinkId(lon, lat, sinks);
                            if (sinkId != null) {
                                weightChange.setSinkId(sinkId);
                            }

                            List<SignCarLonLatEntity> list = signCarLonLatService.list(new QueryWrapper<SignCarLonLatEntity>().eq("car_id", weightChange.getSignCarId()).ge("create_time", weightChange.getUpdateTime()).le("create_time", weightChange.getStartTime()).orderByAsc("id"));
                            double distance = 0;
                            for (int i = 0; i < list.size() - 1; i++) {
                                distance += DistanceUtil.getDistance(list.get(i).getLon(), list.get(i).getLat(), list.get(i + 1).getLon(), list.get(i + 1).getLat());
                            }

                            weightChange.setDistance(distance);

                            this.updateById(weightChange);

                        } else if (change < -1000 && weightChange.getState() == 0) {
                            weightChange.setState(1);
                            weightChange.setEndWeight(Double.parseDouble(Weight));
                            long wuCha = (new Date()).getTime() - carLonLat.getCreateTime().getTime();
                            if (wuCha > 180000) {
                                weightChange.setUpdateTime(new Date());
                            } else {
                                weightChange.setUpdateTime(carLonLat.getCreateTime());
                            }

                            //通过当前记录的经纬度，查询sign_container表中最近的一个经纬度，并且距离小于10米，将这个经纬度的container_id赋值给这条记录
                            //查询sign_container表中最近的一个经纬度，并且距离小于10米
                            List<SignContainerEntity> containers = signContainerService.list();
                            Long containerId = DistanceUtil.getNearestContainerId(lon, lat, containers);
//                            System.out.println("containerId:" + containerId);
                            if (containerId != null) {
//                                System.out.println("成功进入");
                                weightChange.setContainerId(containerId);
                                SignVillageTownEntity villageTown = signVillageTownService.getById(signContainerService.getById(containerId).getVillageId());
                                if (villageTown != null) {
                                    weightChange.setPeriod(villageTown.getSignPeriod());
                                }
                            }
                            this.updateById(weightChange);
                        }
                    }
                }
            }
        }
    }


    @Override
    public List<Map<String, Object>> weightTotalGroupByContainer(SignCarLoadRecordQo qo) {
        List<Map<String, Object>> mapList = this.listMaps(new QueryWrapper<SignCarLoadRecordEntity>().select("container_id as containerId, sum(load_start_weight) as syWeight, sum(TIMESTAMPDIFF(second, start_time, end_time)) as lostTime, count(id) weightCount").eq("state", "2").isNotNull("container_id").eq(qo.getContainerId() != null, "container_id", qo.getContainerId()).in(qo.getContainerIdList() != null && !qo.getContainerIdList().isEmpty(), "container_id", qo.getContainerIdList()).ge(qo.getStartTime() != null, "create_time", qo.getStartTime()).le(qo.getEndTime() != null, "create_time", qo.getEndTime()).like(StringUtils.isNotBlank(qo.getSignCarNumberPlate()), "sign_car_number_plate", qo.getSignCarNumberPlate()).groupBy("container_id").orderBy(StringUtils.isNotBlank(qo.getOrder()), "1".equals(qo.getOrder()), "syWeight"));
        for (Map<String, Object> map : mapList) {
            SignContainerEntity container = signContainerService.findAllContainer((Long) map.get("containerId"));
            if (container != null) {
                SignVillageTownEntity village = signVillageTownService.getById(container.getVillageId());
                if (village != null) {
                    map.put("village", village);
                }
            }
        }
        return mapList;
    }

    @Override
    public List<Map<String, Object>> weightTotalGroupBySink(SignCarLoadRecordQo qo) {
        List<Map<String, Object>> mapList = this.listMaps(new QueryWrapper<SignCarLoadRecordEntity>().select("sink_id as sinkId, sum(load_start_weight) as syWeight, sum(TIMESTAMPDIFF(second, start_time, end_time)) as lostTime, count(id) weightCount").eq("state", "2").eq(qo.getSinkId() != null, "sink_id", qo.getSinkId()).in(qo.getSinkIdList() != null && !qo.getSinkIdList().isEmpty(), "sink_id", qo.getSinkIdList()).ge(qo.getStartTime() != null, "create_time", qo.getStartTime()).le(qo.getEndTime() != null, "create_time", qo.getEndTime()).groupBy("sink_id").orderBy(StringUtils.isNotBlank(qo.getOrder()), "1".equals(qo.getOrder()), "syWeight"));

        for (Map<String, Object> map : mapList) {
//            通过id找到名称
            SignSinkEntity sink = signSinkService.getById((Long) map.get("sinkId"));
//            SignSinkEntity sink = signSinkService.findSink((Long) map.get("sinkId"));
            if (sink != null) {
                map.put("sinkName", sink.getName());
            }
        }

        return mapList;
    }

    @Override
    public PageUtils queryLedger(SignCarLoadRecordQo qo) {
        IPage<SignCarLoadRecordEntity> page = signCarLoadRecordService
                .page(new Query<SignCarLoadRecordEntity>().getPage(qo), new QueryWrapper<SignCarLoadRecordEntity>()
                        .lambda()
                        .eq(SignCarLoadRecordEntity::getState, 2)
                        .eq(qo.getPeriod() != null, SignCarLoadRecordEntity::getPeriod, qo.getPeriod())
                        .eq(qo.getSignCarId() != null, SignCarLoadRecordEntity::getSignCarId, qo.getSignCarId())
                        .eq(qo.getUnitId() != null && qo.getSignCarId() == null, SignCarLoadRecordEntity::getUnitId, qo.getUnitId())
                        .in(qo.getContainerIdList() != null, SignCarLoadRecordEntity::getContainerId, qo.getContainerIdList())
                        .in(qo.getSinkIdList() != null, SignCarLoadRecordEntity::getSinkId, qo.getSinkIdList())
                        .ge(qo.getStartTime() != null, SignCarLoadRecordEntity::getUpdateTime, qo.getStartTime())
                        .le(qo.getEndTime() != null, SignCarLoadRecordEntity::getUpdateTime, qo.getEndTime())
                        .orderByDesc(SignCarLoadRecordEntity::getCreateTime));
        List<SignCarLoadRecordEntity> records = page.getRecords();
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (SignCarLoadRecordEntity record : records) {
            if (record.getStartTime() != null) {
                Map<String, Object> row = new HashMap<>();
                row.put("id", record.getId());
                row.put("sign_car_id", record.getSignCarId());
                row.put("container_id", record.getContainerId());
                row.put("start_weight", record.getStartWeight());
                row.put("create_time", record.getUpdateTime());
                row.put("distance", record.getDistance());
                row.put("end_weight", record.getLoadStartWeight());
                row.put("end_time", record.getStartTime());
                row.put("start_lon", record.getLon());
                row.put("start_lat", record.getLat());
                row.put("end_lon", record.getEndLon());
                row.put("end_lat", record.getEndLat());
                SignContainerEntity container = signContainerService.getById(record.getContainerId());
                if (container != null) {
                    SignVillageTownEntity village = signVillageTownService.getById(container.getVillageId());
                    if (village != null) {
                        row.put("period", village.getSignPeriod());
                        row.put("sheqv", village.getSignVillage());
                    }
                    row.put("container_name", container.getName());
                }
                SignSinkEntity sink = signSinkService.getById(record.getSinkId());
                if (sink != null) {
                    row.put("sink_names", sink.getName());
                }
                resultList.add(row);
            }

        }
        return new PageUtils(resultList, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }


    @Override
    public PageUtils queryLedgerDriver(SignCarLoadRecordQo qo) {
        //获取账户信息
        IPage<SignCarLoadRecordEntity> page = signCarLoadRecordService.page(new Query<SignCarLoadRecordEntity>().getPage(qo), new QueryWrapper<SignCarLoadRecordEntity>().lambda().eq(SignCarLoadRecordEntity::getSignCarId, qo.getSignCarId()).ge(qo.getStartTime() != null, SignCarLoadRecordEntity::getCreateTime, qo.getStartTime()).le(qo.getEndTime() != null, SignCarLoadRecordEntity::getCreateTime, qo.getEndTime()).orderByDesc(SignCarLoadRecordEntity::getCreateTime));
        List<SignCarLoadRecordEntity> records = page.getRecords();
//        List<Map<String, Object>> resultList = new ArrayList<>();

        for (SignCarLoadRecordEntity record : records) {


            SignContainerEntity container = signContainerService.getById(record.getContainerId());
            if (container != null) {
//                SignVillageTownEntity village = signVillageTownService.getById(container.getVillageId());
                record.setSignContainerEntity(container);
            }
            SignSinkEntity sink = signSinkService.getById(record.getSinkId());
            if (sink != null) {
                record.setSignSinkEntity(sink);
            }

//            resultList.add(row);
        }
        SignCarLoadRecordEntity carLoadRecord = signCarLoadRecordService.getOne(new QueryWrapper<SignCarLoadRecordEntity>().eq("sign_car_id", qo.getSignCarId())
//                .eq("state", 0)
                .orderByDesc("id").last("limit 1"));
        if (carLoadRecord.getState() == 0) {
            carLoadRecord.setCreateTime(new Date());
            carLoadRecord.setUpdateTime(new Date());
            this.updateById(carLoadRecord);
        }

        page.setRecords(records);

        return new PageUtils(page);
    }

    @Override
    public PageUtils totalTable(SignCarLoadRecordQo qo) {
        IPage<SignCarLoadRecordEntity> page = signCarLoadRecordService.page(new Query<SignCarLoadRecordEntity>().getPage(qo),
//        IPage<SignCarLoadRecordEntity> page = this.page(new Query<SignCarLoadRecordEntity>().getPage(qo),
                new QueryWrapper<SignCarLoadRecordEntity>().lambda().eq(SignCarLoadRecordEntity::getState, 2).ge(qo.getStartTime() != null, SignCarLoadRecordEntity::getUpdateTime, qo.getStartTime()).le(qo.getEndTime() != null, SignCarLoadRecordEntity::getUpdateTime, qo.getEndTime()).orderByDesc(SignCarLoadRecordEntity::getEndTime));
        for (SignCarLoadRecordEntity entity : page.getRecords()) {
            if (entity.getSinkId() != null) {
                SignSinkEntity sink = signSinkService.getById(entity.getSinkId());
                entity.setSignSinkEntity(sink);
            }
            SignContainerEntity container = signContainerService.getById(entity.getContainerId());
            if (container != null) {
                entity.setSignContainerEntity(container);
                if (entity.getSignContainerEntity().getVillageId() != null) {
                    entity.setSignVillageTownEntity(signVillageTownService.getById(entity.getSignContainerEntity().getVillageId()));
                }
            }
            entity.setSignCarEntity(signCarService.getById(entity.getSignCarId()));
            entity.setSignUnitEntity(signUnitService.getById(entity.getSignCarEntity().getCtUnitId()));
            entity.setSignFleetEntity(signFleetService.getById(entity.getSignCarEntity().getFleetId()));
            entity.setUserEntity(sysUserService.getById(entity.getSignCarEntity().getDriverId()));
        }
//        定义一个数组
//        Map<String, SignCarLoadRecordEntity> mergedEntities = new HashMap<>();
//
//        for (SignCarLoadRecordEntity entity : page.getRecords()) {
//            @Deprecated int newDay = entity.getCreateTime().getYear() + entity.getCreateTime().getMonth() + entity.getCreateTime().getDay();
//            String key = entity.getSignCarId() + "-" + entity.getContainerId() + "-" + entity.getSinkId() + "-" + newDay + "-" + entity.getDistance() + "-" + entity.getLoadStartWeight();
//            SignCarLoadRecordEntity mergedEntity = mergedEntities.get(key);
//            if (mergedEntity == null) {
//                // If the merged entity doesn't exist yet, create a new one
//                mergedEntity = new SignCarLoadRecordEntity();
//                mergedEntity.setId(entity.getId());
//                mergedEntity.setCreateTime(entity.getUpdateTime());
//                mergedEntity.setEndTime(entity.getStartTime());
//                mergedEntity.setStartWeight(entity.getStartWeight());
//                mergedEntity.setSignSinkEntity(entity.getSignSinkEntity());
//                mergedEntity.setSignCarEntity(entity.getSignCarEntity());
//                mergedEntity.setSignCarId(entity.getSignCarId());
//                mergedEntity.setContainerId(entity.getContainerId());
//                mergedEntity.setSinkId(entity.getSinkId());
//                mergedEntity.setEndWeight(entity.getLoadStartWeight());
//                mergedEntity.setDistance(entity.getDistance());
//                mergedEntity.setSignUnitEntity(entity.getSignUnitEntity());
//                mergedEntity.setSignVillageTownEntity(entity.getSignVillageTownEntity());
//                mergedEntity.setCount(entity.getCount());
//                mergedEntity.setUserEntity(entity.getUserEntity());
//                mergedEntities.put(key, mergedEntity);
//
//            } else {
//                // If the merged entity already exists, update its values
//                mergedEntity.setEndWeight(mergedEntity.getEndWeight() + entity.getEndWeight());
//                mergedEntity.setDistance(mergedEntity.getDistance() + entity.getDistance());
//                //给mergedEntity创建一个属性，用来记录合并的次数
//                mergedEntity.setCount(mergedEntity.getCount() + 1);
//            }
//        }
//        page.setRecords(new ArrayList<>(mergedEntities.values()));
        return new PageUtils(page);
    }


    @Override
    public PageUtils queryPage(SignCarLoadRecordQo qo) {
        IPage<SignCarLoadRecordEntity> page = this.page(new Query<SignCarLoadRecordEntity>().getPage(qo), new QueryWrapper<SignCarLoadRecordEntity>().lambda().eq(qo.getState() != null, SignCarLoadRecordEntity::getState, qo.getState()).eq(qo.getSignCarId() != null, SignCarLoadRecordEntity::getSignCarId, qo.getSignCarId()).like(StringUtils.isNotBlank(qo.getSignCarNumberPlate()), SignCarLoadRecordEntity::getSignCarNumberPlate, qo.getSignCarNumberPlate()).ge(qo.getStartTime() != null, SignCarLoadRecordEntity::getCreateTime, qo.getStartTime()).le(qo.getEndTime() != null, SignCarLoadRecordEntity::getCreateTime, qo.getEndTime()).orderByDesc(SignCarLoadRecordEntity::getCreateTime));
        for (SignCarLoadRecordEntity entity : page.getRecords()) {
            SignCarEntity car = signCarService.getById(entity.getSignCarId());
            if (car != null) {
                SysUserEntity user = sysUserService.getById(car.getDriverId());
                entity.setUserEntity(user);
            }
            entity.setSignCarEntity(car);
        }

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageWeightTotalGroupByCar(SignCarLoadRecordQo qo) {

        List<Map<String, Object>> list = this.weightTotalGroupByCar(qo);

        IPage<Map<String, Object>> page = new Query<Map<String, Object>>().getPage(qo);
        //当前页
        long current = page.getCurrent();
        //每页数据条数
        long size = page.getSize();
        int count = list.size();
        List<Map<String, Object>> pageList = new ArrayList<>();
        //计算当前页第一条数据的下标
        long currId = current > 1 ? (current - 1) * size : 0;
        for (int i = 0; i < size && i < count - currId; i++) {
            pageList.add(list.get((int) currId + i));
        }
        page.setSize(size);
        page.setCurrent(current);
        page.setTotal(count);
        //计算分页总页数
        page.setPages(count % 10 == 0 ? count / 10 : count / 10 + 1);
        page.setRecords(pageList);

        return new PageUtils(page);

    }

    @Override
    public List<Map<String, Object>> weightTotalGroupByCar(SignCarLoadRecordQo qo) {
        List<Map<String, Object>> mapList = this.listMaps(new QueryWrapper<SignCarLoadRecordEntity>().select("sign_car_number_plate AS signCarNumberPlate, sign_car_id as signCarId, sum(load_start_weight) as syWeight,sum(distance) as distance, sum(TIMESTAMPDIFF(second, update_time, end_time)) as lostTime, count(id) taskCount").eq("state", 2).eq(qo.getPeriod() != null, "period", qo.getPeriod()).in(qo.getCarIdList() != null && qo.getCarIdList().size() > 0, "sign_car_id", qo.getCarIdList()).ge(qo.getStartTime() != null, "update_time", qo.getStartTime()).le(qo.getEndTime() != null, "update_time", qo.getEndTime()).groupBy("sign_car_id,sign_car_number_plate").orderBy(StringUtils.isNotBlank(qo.getOrder()), "1".equals(qo.getOrder()), "syWeight"));

        return mapList;
    }

    @Override
    public List<Map<String, Object>> weightTotalGroupByTimeLength(SignCarLoadRecordQo qo) {
        List<Map<String, Object>> mapList = this.listMaps(new QueryWrapper<SignCarLoadRecordEntity>().select("SUBSTR(update_time, 1, " + qo.getTimeLength() + ") data_time, sum(load_start_weight) as syWeight, sum(TIMESTAMPDIFF(second, create_time, update_time)) as lostTime, count(id) taskCount").eq("state", 2).ge(qo.getStartTime() != null, "update_time", qo.getStartTime()).le(qo.getEndTime() != null, "update_time", qo.getEndTime()).groupBy("data_time").orderBy(StringUtils.isNotBlank(qo.getOrder()), "1".equals(qo.getOrder()), "data_time"));
        return mapList;
    }

    @Override
    public List<Map<String, Object>> weightGroupByCarAndTime(SignCarLoadRecordQo qo) {
        List<Map<String, Object>> mapList = this.listMaps(new QueryWrapper<SignCarLoadRecordEntity>().select("DATE(update_time) AS date, sum(load_start_weight) as syWeight,sum(distance) as distance, sum(TIMESTAMPDIFF(second, create_time, update_time)) as lostTime, count(id) taskCount").eq("state", 2).eq(qo.getSignCarId() != null, "sign_car_id", qo.getSignCarId()).ge(qo.getStartTime() != null, "update_time", qo.getStartTime()).le(qo.getEndTime() != null, "update_time", qo.getEndTime()).groupBy("date"));
        return mapList;
    }

    public R submit(SignCarLoadRecordEntity qo) {
        SignCarEntity car = signCarService.getOne(new QueryWrapper<SignCarEntity>().eq("id", qo.getSignCarId()));
        if (car.getRemark() != null) {

            if (qo.getContainerId() != null && qo.getContainerId() == 0) {
                qo.setContainerId(null);
            }
            if (qo.getSinkId() != null && qo.getSinkId() == 0) {
                qo.setSinkId(null);
            }
//            if (qo.getRemark() == null && qo.getContainerId() == null && qo.getSinkId() == null) {
//                System.out.println(qo.getSignCarId());
//                return R.error(-1,"请填写当前点位");
//            }
//            System.out.println(qo.getSignCarId());
            SignCarLoadRecordEntity load = signCarLoadRecordService.getOne(new QueryWrapper<SignCarLoadRecordEntity>().eq("sign_car_id", qo.getSignCarId()).orderByDesc("id").last("limit 1"));
            if (load.getState() == 0 && qo.getState() == 1) {
                SignCarLoadRecordEntity loadRecord = signCarLoadRecordService.getOne(new QueryWrapper<SignCarLoadRecordEntity>().eq("sign_car_id", qo.getSignCarId()).eq("state", 2).orderByDesc("create_time").last("limit 1"));
                long diff = (new Date()).getTime() - loadRecord.getEndTime().getTime();
                if (diff < 120000) {
                    return R.error("提交时间间隔太短，错误操作！！");
                }
                SignCarLonLatEntity lonLat = signCarLonLatService.getOne(new QueryWrapper<SignCarLonLatEntity>().eq("car_id", qo.getSignCarId()).orderByDesc("create_time").last("limit 1"));
                load.setState(1);

                if (lonLat != null) {
                    if (lonLat.getWeight() != null) {
                        load.setEndWeight(Double.parseDouble(lonLat.getWeight()));
                    } else {
                        load.setEndWeight(0.0);
                    }
                    long wuCha = (new Date()).getTime() - lonLat.getCreateTime().getTime();
                    if (wuCha > 180000) {
                        load.setUpdateTime(new Date());
                    } else {
                        load.setUpdateTime(lonLat.getCreateTime());
                    }

                } else {
                    load.setEndWeight(0.0);
                    load.setUpdateTime(new Date());
                }
                Long containerId;
                if (qo.getContainerId() != null) {
                    containerId = qo.getContainerId();
                } else {
                    if (lonLat != null) {
                        List<SignContainerEntity> containers = signContainerService.list();
                        containerId = DistanceUtil.getNearestContainerId(lonLat.getLon(), lonLat.getLat(), containers);
                    } else {
                        return R.error("没有读取到经纬度");
                    }
                }
                if (containerId == null && (qo.getRemark() == null || qo.getRemark().isEmpty())) {
                    return R.error("请提交名称");
                }

                if (containerId != null) {
//                    System.out.println("测试" + containerId);
                    load.setContainerId(containerId);
                    SignVillageTownEntity villageTown = signVillageTownService.getById(signContainerService.getById(containerId).getVillageId());
                    if (villageTown != null) {
                        load.setPeriod(villageTown.getSignPeriod());
                    }
                }
                if (qo.getRemark() != null && !qo.getRemark().isEmpty()) {
                    if (containerId != null) {
                        SignContainerEntity container = signContainerService.getById(containerId);
                        container.setName(qo.getRemark());
                        container.setRemark("司机修改");
                        signContainerService.updateById(container);
                    } else {
                        SignContainerEntity container = new SignContainerEntity();
                        container.setName(qo.getRemark());
                        container.setInitCalCount(100);
                        container.setContainerCapacity(200.0);
                        container.setContainerWarningLiquidValue(180.0);
                        StringBuilder sb = new StringBuilder();
                        Random random = new Random();
                        for (int i = 0; i < 10; i++) {
                            sb.append((char) ('a' + random.nextInt('z' - 'a' + 1)));
                        }
                        container.setSensorId(String.valueOf(sb));
                        container.setLon(lonLat.getLon());
                        container.setLat(lonLat.getLat());
                        container.setRemark("司机提交");
                        signContainerService.save(container);
                        load.setContainerId(container.getId());
                    }
                }
                this.updateById(load);

            }

            if (load.getState() == 1 && qo.getState() == 2) {
                if (qo.getSinkId() == null && (qo.getRemark() == null || qo.getRemark().isEmpty())) {
                    return R.error("请提交名称");
                }
                SignCarLoadRecordEntity loadRecord = signCarLoadRecordService.getOne(new QueryWrapper<SignCarLoadRecordEntity>().eq("sign_car_id", qo.getSignCarId()).eq("state", 1).orderByDesc("create_time").last("limit 1"));
                long diff = (new Date()).getTime() - loadRecord.getUpdateTime().getTime();
                if (diff < 120000) {
                    return R.error("提交时间间隔太短，错误操作！！");
                }
                //卸货
                SignCarLonLatEntity lonLat = signCarLonLatService.getOne(new QueryWrapper<SignCarLonLatEntity>().eq("car_id", qo.getSignCarId()).orderByDesc("create_time").last("limit 1"));
                load.setState(2);
                if (qo.getSignCarId() == 154L) {
                    load.setStartWeight(19510);
                    SignCarLonLatEntity special = signCarLonLatService.getOne(new QueryWrapper<SignCarLonLatEntity>().select("MAX(CAST(weight AS UNSIGNED))").eq("car_id", 154).gt("create_time", loadRecord.getCreateTime()).lt("create_time", new Date()));
                    if (special != null) {
                        load.setLoadStartWeight(Double.parseDouble(special.getWeight()));
                        System.out.println("8107的最高点为" + special.getWeight());
                    }
                }
                Map<Long, Double> vehicleWeights = new HashMap<>();
                vehicleWeights.put(136L, 4800.0);
                vehicleWeights.put(137L, 8100.0);
                vehicleWeights.put(138L, 8600.0);
                vehicleWeights.put(139L, 8600.0);
                vehicleWeights.put(140L, 11700.0);
                vehicleWeights.put(141L, 8700.0);
                vehicleWeights.put(142L, 8700.0);
                vehicleWeights.put(143L, 8700.0);
                vehicleWeights.put(144L, 8700.0);
                vehicleWeights.put(145L, 4800.0);
                vehicleWeights.put(146L, 4600.0);
                vehicleWeights.put(147L, 8100.0);
                vehicleWeights.put(148L, 4600.0);
                vehicleWeights.put(154L, 19000.0);

                Map<Long, Double> otherWeights = new HashMap<>();
                otherWeights.put(153L, 12800.0);
                otherWeights.put(155L, 10800.0);
                otherWeights.put(158L, 8800.0);
                otherWeights.put(157L, 8800.0);

                if (otherWeights.containsKey(qo.getSignCarId())) {
                    double x = otherWeights.get(load.getSignCarId());

                    Random rand = new Random();
                    double minWeight = x;
                    double maxWeight = x + 300;
                    double randomWeight = minWeight + rand.nextDouble() * (maxWeight - minWeight);
                    double tmp = randomWeight / 10;
                    int newWeight = (int) tmp * 10;
                    load.setLoadStartWeight(newWeight);
                } else if (vehicleWeights.containsKey(qo.getSignCarId())) {
                    //如果是这些车辆，根据后面的值取94%-99%，最小单位10
                    double x = vehicleWeights.get(load.getSignCarId());

                    Random rand = new Random();
                    double minWeight = x;
                    double maxWeight = x + 500;
                    double randomWeight = minWeight + rand.nextDouble() * (maxWeight - minWeight);
                    double tmp = randomWeight / 10;
                    int newWeight = (int) tmp * 10;
                    load.setLoadStartWeight(newWeight);

                } else {
//                    load.setLoadStartWeight(1000.0);
                    load.setLoadEndWeight(Double.parseDouble(lonLat.getWeight()));
                }

                load.setEndTime(lonLat.getCreateTime());
                List<SignCarLonLatEntity> list = signCarLonLatService.list(new QueryWrapper<SignCarLonLatEntity>().eq("car_id", load.getSignCarId()).ge("create_time", load.getUpdateTime()).le("create_time", load.getStartTime()).orderByAsc("id"));
                double distance = 0;
                for (int i = 0; i < list.size() - 1; i++) {

                    distance += DistanceUtil.getDistance(list.get(i).getLon(), list.get(i).getLat(), list.get(i + 1).getLon(), list.get(i + 1).getLat());
                }
                load.setDistance(distance);
                if (qo.getSinkId() != null) {
                    load.setSinkId(qo.getSinkId());
                }
                if (qo.getRemark() != null && !qo.getRemark().isEmpty()) {
                    if (qo.getSinkId() != null) {
                        SignSinkEntity sink = signSinkService.getById(qo.getSinkId());
                        sink.setName(qo.getRemark());
                        sink.setRemark("司机修改");
                        signSinkService.updateById(sink);
                    } else {
                        SignSinkEntity sink = new SignSinkEntity();
                        sink.setName(qo.getRemark());
                        sink.setSinkCapacity(200.0);
                        sink.setSinkWarningLiquidValue(180.0);
                        sink.setSinkType("2");
                        sink.setJiedao(qo.getRemark());
                        sink.setSheqv(qo.getRemark());
                        StringBuilder sb = new StringBuilder();
                        Random random = new Random();
                        for (int i = 0; i < 10; i++) {
                            sb.append((char) ('a' + random.nextInt('z' - 'a' + 1)));
                        }
                        sink.setSensorId(String.valueOf(sb));
                        sink.setLon(lonLat.getLon());
                        sink.setLat(lonLat.getLat());
                        sink.setRemark("司机提交");
                        signSinkService.save(sink);
                        load.setSinkId(sink.getId());
                    }

                }
                this.updateById(load);

                SignCarLoadRecordEntity newLoad = new SignCarLoadRecordEntity();
                newLoad.setLon(lonLat.getLon());
                newLoad.setLat(lonLat.getLat());
                newLoad.setState(0);
                newLoad.setSignCarId(qo.getSignCarId());
                SignCarEntity theCar = signCarService.getById(qo.getSignCarId());
                newLoad.setUnitId(theCar.getCtUnitId());
                newLoad.setSignCarNumberPlate(load.getSignCarNumberPlate());
                newLoad.setStartWeight(0);
                newLoad.setCreateTime(new Date());
                this.save(newLoad);
            }

        }


        return R.ok();
    }

    @Override
    public SignContainerEntity getContainer(SignCarLoadRecordEntity qo) {
        List<SignContainerEntity> containers = signContainerService.list();
        SignCarLonLatEntity lonLat = signCarLonLatService.getOne(new QueryWrapper<SignCarLonLatEntity>().eq("car_id", qo.getSignCarId()).orderByDesc("create_time").last("limit 1"));
        Long containerId = DistanceUtil.getNearestContainerId(lonLat.getLon(), lonLat.getLat(), containers);
        return signContainerService.getById(containerId);
//        return signContainerService.getById(192);
    }

    @Override
    public SignSinkEntity getSink(SignCarLoadRecordEntity qo) {
        List<SignSinkEntity> sinks = signSinkService.list();
        SignCarLonLatEntity lonLat = signCarLonLatService.getOne(new QueryWrapper<SignCarLonLatEntity>().eq("car_id", qo.getSignCarId()).orderByDesc("create_time").last("limit 1"));
        Long sinkId = DistanceUtil.getNearestSinkId(lonLat.getLon(), lonLat.getLat(), sinks);
        return signSinkService.getById(sinkId);
//        return signSinkService.getById(154);
    }

    @Override
    public Double weightTotal(SignCarLoadRecordQo qo) {
        IPage<SignCarLoadRecordEntity> page = signCarLoadRecordService.page(new Query<SignCarLoadRecordEntity>().getPage(qo), new QueryWrapper<SignCarLoadRecordEntity>().lambda().eq(SignCarLoadRecordEntity::getState, 2).ge(qo.getStartTime() != null, SignCarLoadRecordEntity::getUpdateTime, qo.getStartTime()).le(qo.getEndTime() != null, SignCarLoadRecordEntity::getUpdateTime, qo.getEndTime()).orderByDesc(SignCarLoadRecordEntity::getCreateTime));
        List<SignCarLoadRecordEntity> records = page.getRecords();
        //取records中的load_start_weight字段值相加
        Double total = 0.0;
        if (records != null && records.size() > 0) {
            for (SignCarLoadRecordEntity record : records) {
                total += record.getLoadStartWeight();
            }
            return total;
        }
        return total;

    }

}